﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using PhantomRealm.Common.Utilities;
using System.Collections.Generic;
using Terraria;
using Terraria.GameContent;
using Terraria.GameContent.Bestiary;
using Terraria.GameContent.ItemDropRules;
using Terraria.ID;
using Terraria.ModLoader;

namespace PhantomRealm.Content.NPCs.Enemies
{
    public class AuroraSkeleton : ModNPC
    {
        private float auroraTime;
        private readonly List<Vector2> positionHistory = [];
        private const int HISTORY_LENGTH = 4; 
        private readonly Color AuroraColor1 = new(0, 143, 233);
        private readonly Color AuroraColor2 = new(0, 255, 255);
        private readonly Color AuroraColor3 = new(9, 231, 167);
        private readonly Color AuroraColor4 = new(0, 255, 100);
        public override void SetStaticDefaults()
        {
            Main.npcFrameCount[Type] = Main.npcFrameCount[NPCID.AngryBones];
            NPCID.Sets.NPCBestiaryDrawModifiers value = new()
            {
                Velocity = 1
            };
            NPCID.Sets.NPCBestiaryDrawOffset.Add(Type, value);
        }

        public override void SetDefaults()
        {
            NPC.width = 18;
            NPC.height = 40;
            NPC.aiStyle = NPCAIStyleID.Fighter;
            NPC.damage = 26;
            NPC.defense = 8;
            NPC.lifeMax = 80;
            NPC.HitSound = SoundID.NPCHit2;
            NPC.DeathSound = SoundID.NPCDeath2;
            NPC.knockBackResist = 0.8f;
            NPC.value = 130f;
            AIType = NPCID.AngryBones;
            AnimationType = NPCID.AngryBones;
            if (NPC.IsABestiaryIconDummy)
            {
                NPC.color = Color.Lerp(new Color(9, 231, 167), new Color(0, 255, 255),
                    (float)(System.Math.Sin(Main.GlobalTimeWrappedHourly * 2f) * 0.5f + 0.5f));
            }
        }
        public override void ModifyNPCLoot(NPCLoot npcLoot)
        {
            npcLoot.Add(ItemDropRule.Common(ModContent.ItemType<Items.Materials.AuroraDust>(), 2, 1, 5));
        }

        public override void SetBestiary(BestiaryDatabase database, BestiaryEntry bestiaryEntry)
        {
            bestiaryEntry.Info.AddRange([
                BestiaryDatabaseNPCsPopulator.CommonTags.SpawnConditions.Times.NightTime,
                BestiaryDatabaseNPCsPopulator.CommonTags.SpawnConditions.Biomes.Snow,
               new FlavorTextBestiaryInfoElement("Mods.PhantomRealm.NPCs.AuroraSkeleton.Description")
            ]);
        }
        public override float SpawnChance(NPCSpawnInfo spawnInfo)
        {
            if (spawnInfo.Player.ZoneSnow() && spawnInfo.Player.ZoneAurora() && spawnInfo.Player.IsNight() && NPC.downedMechBoss2)
            {
                return 0.12f;
            }
            return 0f;
        }
        public override void AI()
        {
            auroraTime += 0.05f;
            if (auroraTime > 1000f)
            {
                auroraTime = 0f;
            }
            if (NPC.IsABestiaryIconDummy)
            {
                NPC.color = Color.Lerp(new Color(9, 231, 167), new Color(0, 255, 255),
                    (float)(System.Math.Sin(Main.GlobalTimeWrappedHourly * 3f) * 0.5f + 0.5f));
            }
            if (!Main.gameMenu && !Main.dedServ && !NPC.IsABestiaryIconDummy)
            {
                UpdatePositionHistory();
            }
            UpdateDirection();
        }

        private void UpdateDirection()
        {
            if (System.Math.Abs(NPC.velocity.X) > 0.1f)
            {
                NPC.direction = NPC.velocity.X > 0 ? 1 : -1;
                NPC.spriteDirection = NPC.direction;
            }
        }

        private void UpdatePositionHistory()
        {
            positionHistory.Insert(0, NPC.Center);
            if (positionHistory.Count > HISTORY_LENGTH)
            {
                positionHistory.RemoveAt(positionHistory.Count - 1);
            }
        }

        public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor)
        {
            if (NPC.IsABestiaryIconDummy)
            {          
                return true;
            }
            DrawSimpleTrail(spriteBatch, screenPos);
            DrawSimpleBody(spriteBatch, screenPos);
            return false;
        }
        private void DrawSimpleBody(SpriteBatch spriteBatch, Vector2 screenPos)
        {
            Texture2D texture = TextureAssets.Npc[NPC.type].Value;
            Rectangle frame = NPC.frame;
            Vector2 origin = new(frame.Width * 0.5f, frame.Height * 0.5f);
            Vector2 drawPos = NPC.Center - screenPos;
            drawPos.Y += NPC.gfxOffY - 6;
            SpriteEffects spriteEffects = NPC.spriteDirection == 1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
            for (int i = 0; i < 3; i++)
            {
                float timeOffset = auroraTime + i * 0.3f;
                float pulse = (float)System.Math.Sin(timeOffset * 2f) * 0.2f + 0.8f;
                float scaleMultiplier = 1.0f + i * 0.03f;
                float alpha = 0.6f / (i + 1) * pulse;
                Color layerColor = i switch
                {
                    0 => AuroraColor3, 
                    1 => AuroraColor2,
                    _ => AuroraColor1  
                };

                layerColor.A = (byte)(alpha * 255);
                Vector2 offset = new Vector2(
                    (float)System.Math.Sin(timeOffset * 1.5f + i) * 0.5f,
                    (float)System.Math.Cos(timeOffset * 1.2f + i) * 0.5f
                );

                spriteBatch.Draw(texture, drawPos + offset, frame, layerColor,
                    NPC.rotation, origin, NPC.scale * scaleMultiplier, spriteEffects, 0f);
            }
            Color baseColor = AuroraColor3;
            baseColor.A = 200;
            spriteBatch.Draw(texture, drawPos, frame, baseColor,
                NPC.rotation, origin, NPC.scale, spriteEffects, 0f);
        }
        private void DrawSimpleTrail(SpriteBatch spriteBatch, Vector2 screenPos)
        {
            Texture2D texture = TextureAssets.Npc[NPC.type].Value;
            Rectangle frame = NPC.frame;
            Vector2 origin = new(frame.Width * 0.5f, frame.Height * 0.5f);
            SpriteEffects spriteEffects = NPC.spriteDirection == 1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
            for (int i = positionHistory.Count - 1; i >= 0; i--)
            {
                float progress = (float)i / HISTORY_LENGTH;
                float alpha = 0.3f * (1f - progress); 
                Color trailColor = progress switch
                {
                    < 0.25f => AuroraColor3, 
                    < 0.5f => AuroraColor2, 
                    < 0.75f => AuroraColor1,
                    _ => AuroraColor4       
                };

                trailColor.A = (byte)(alpha * 255);
                Vector2 drawPos = positionHistory[i] - screenPos;
                drawPos.Y += NPC.gfxOffY - 6;
                spriteBatch.Draw(texture, drawPos, frame, trailColor,
                    NPC.rotation, origin, NPC.scale, spriteEffects, 0f);
            }
        }

        public override void PostDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor)
        {
            if (NPC.IsABestiaryIconDummy)
            {
                return;
            }
            DrawSimpleHighlights(spriteBatch, screenPos);
        }

        private void DrawSimpleHighlights(SpriteBatch spriteBatch, Vector2 screenPos)
        {
            Texture2D texture = TextureAssets.Npc[NPC.type].Value;
            Rectangle frame = NPC.frame;
            Vector2 origin = new Vector2(frame.Width * 0.5f, frame.Height * 0.5f);
            Vector2 drawPos = NPC.Center - screenPos;
            drawPos.Y += NPC.gfxOffY - 6;
            SpriteEffects spriteEffects = NPC.spriteDirection == 1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
            float pulse = (float)System.Math.Sin(auroraTime * 3f) * 0.3f + 0.7f;
            Color highlightColor = AuroraColor2;
            highlightColor.A = (byte)(100 * pulse);
            spriteBatch.Draw(texture, drawPos, frame, highlightColor,
                NPC.rotation, origin, NPC.scale * 1.02f, spriteEffects, 0f);
        }

        public override void HitEffect(NPC.HitInfo hit)
        {
            if (NPC.life <= 0 && !NPC.IsABestiaryIconDummy)
            {
                for (int i = 0; i < 15; i++)
                {
                    Vector2 speed = new(Main.rand.NextFloat(-3f, 3f), Main.rand.NextFloat(-4f, -1f));
                    Color particleColor = (i % 4) switch
                    {
                        0 => AuroraColor1,
                        1 => AuroraColor2,
                        2 => AuroraColor3,
                        _ => AuroraColor4
                    };
                    Dust dust = Dust.NewDustPerfect(NPC.Center, DustID.Clentaminator_Blue, speed, 0, particleColor, 1.5f);
                    dust.noGravity = true;
                    dust.velocity *= 1.2f;
                }
            }
            else if (!NPC.IsABestiaryIconDummy)
            {
                for (int i = 0; i < 3; i++)
                {
                    Dust dust = Dust.NewDustDirect(NPC.position, NPC.width, NPC.height, DustID.Clentaminator_Cyan, 0f, 0f, 100, AuroraColor3, 0.8f);
                    dust.noGravity = true;
                }
            }
        }

        public override void DrawBehind(int index)
        {
            if (!NPC.IsABestiaryIconDummy)
            {
                Vector3 lightColor = new Vector3(0.035f, 0.91f, 0.65f);
                Lighting.AddLight(NPC.Center, lightColor * 0.6f);
            }
        }
    }
}